#include <CoOS.h>
#include <string.h>
#include <stdio.h>
#include <stm32f10x_gpio.h>
#include <stm32f10x_rcc.h>
#include <stm32f10x_usart.h>
#include <Config.h>
#include <ParseString.h>
#include <USART_TERM.h>

extern USART_TypeDef* USARTx;

#define buffersize 256
#if buffersize < 2
Buffer size is too small!
#endif
static char UBuffer[buffersize];
static unsigned int UBuffer_pos = 0;
static unsigned int count_endline = 0;

void USARTTermInit(void) {
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	/* Enable GPIOA clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA
			| RCC_APB2Periph_AFIO, ENABLE);

	/* Configure USART1 Rx (PA10) as input floating */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* Configure USART1 Tx (PA9) as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl
			= USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART1, &USART_InitStructure);
	/* Enable USART1 */
	USART_Cmd(USART1, ENABLE);
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}

/*********************************************************************
 * get a string from USARTx
 *
 * string is put in (char* str)
 *********************************************************************/
void uGets(char *out_str, unsigned int Flag_all) {
	if (Flag_all == 0) {
		if (count_endline != 0) {
			strcpy(out_str, UBuffer);
			UBuffer_pos = 0;
			ClearString(UBuffer);
			count_endline = 0;
		} else {
			strcpy(out_str, "");
		}
	} else {
		strcpy(out_str, UBuffer);
		UBuffer_pos = 0;
		ClearString(UBuffer);
		count_endline = 0;
	}
}

/******************************************************************************
 * USART1 _ IRQHandler
 *
 * ****************************************************************************/
void USART1_IRQHandler(void) {
	CoEnterISR();
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) {
		UBuffer[UBuffer_pos] = USART_ReceiveData(USART1);
		if (UBuffer[UBuffer_pos] == '\r') {
			count_endline++;
		}
		UBuffer_pos++;
		//		if ((UBuffer[UBuffer_pos] < ' ') || (UBuffer[UBuffer_pos] > '~')) {
		//			if (UBuffer[UBuffer_pos] == '\r') {
		//				count_endline++;
		//				UBuffer_pos++;
		//			} else if (UBuffer[UBuffer_pos] == '\n') {
		//				UBuffer_pos++;
		//			} else {
		//				UBuffer[UBuffer_pos] = '\0';
		//			}
		//		} else {
		//			UBuffer_pos++;
		//		}
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
	CoExitISR();
}

